﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Drawing;
using System.Diagnostics;
using System.Globalization;

using Microsoft.WindowsMobile.Status;
using Microsoft.WindowsMobile.PocketOutlook;

using iPhoneUI.Shell;

namespace iPhoneUI.Widgets
{
    public class Appointments : TextWidget
    {
        private IImage m_icon;
        private AppointmentHelper m_helper = new AppointmentHelper();

        public Appointments()
        {
            SubjectFont = ShellConfig.CreateFont(10, FontStyle.Bold);
        }

        public Font SubjectFont { get; set; }

        public string AppointmentImage { get; set; }

        protected override void OnSetOwner()
        {
            m_icon = ShellConfig.CreatePerPixelAlphaImage(AppointmentImage);

            RegisterSystemStateChange(SystemProperty.CalendarHomeScreenAppointment);
            RegisterSystemStateChange(SystemProperty.CalendarNextAppointment);
            RegisterSystemStateChange(SystemProperty.CalendarAppointment);
            RegisterSystemStateChange(SystemProperty.CalendarEvent);

            m_helper.Refresh();

            base.OnSetOwner();
        }

        protected override void OnSystemStateChanged(SystemState property, object newValue)
        {
            m_helper.Refresh();
            base.OnSystemStateChanged(property, newValue);
        }

        protected override void OnDispose()
        {
            SubjectFont.SafeDispose();
            m_icon = null;
            base.OnDispose();
        }

        protected override void OnDraw(Canvas canvas, Rectangle clipBounds)
        {
            int y = Location.Y + 2;
            foreach(Appointment a in m_helper.Appointments.Take(3)) // only draw 3 appointments
                y = DrawAppointment(a, canvas, y);
        }

        private int DrawAppointment(Appointment appointment, Canvas canvas, int y)
        {
            if (appointment != null)
            {
                Size iconSize = m_icon.Size();
                int x = Location.X + 5;

                canvas.AlphaBlend(m_icon, new Rectangle(x, y, iconSize.Width, iconSize.Height));
                x += iconSize.Width + 2;

                using (Brush b = new SolidBrush(ForeColor))
                {
                    y = DrawString(canvas, b, SubjectFont, appointment.Subject, x, y);
                    y = DrawString(canvas, b, Font, GetAppointmentDetail(appointment), x, y) + 4;
                }
            }

            return y;
        }

        private int DrawString(Canvas canvas, Brush b, Font font, string text, int x, int y)
        {
            if (string.IsNullOrEmpty(text) == false)
            {
                SizeF size = canvas.MeasureString(text, font);
                RectangleF rect = new RectangleF(x, y, Size.Width - x, size.Height);
                if (size.Width > rect.Width)
                    rect.Height *= 2; // if the text length is greater than our alloted width double the height

                canvas.DrawString(text, font, b, rect);
                y += (int)rect.Height;
            }

            return y;
        }

        private static string GetAppointmentDetail(Appointment appointment)
        {
            if (appointment.AllDayEvent)
                return String.Empty;
            
            string time = GetTimeDetail(appointment);
            if (string.IsNullOrEmpty(appointment.Location) == false)
                return string.Format("{0} ({1})", time, appointment.Location);

            return time;
        }

        private static string GetTimeDetail(Appointment appointment)
        {
            if (appointment.AllDayEvent)
                return String.Empty;

            CultureInfo culture = CultureInfo.CurrentUICulture;
            string day = GetDayDetail(appointment.Start, culture);

            if (appointment.Start.Date != appointment.End.Date)
                return string.Format("{0}{1}-Multi-day event", day, appointment.Start.ToString(culture.DateTimeFormat.ShortTimePattern, culture));

            return string.Format("{0}{1}-{2}", day, appointment.Start.ToString(culture.DateTimeFormat.ShortTimePattern, culture), appointment.End.ToString(culture.DateTimeFormat.ShortTimePattern, culture));
        }

        private static string GetDayDetail(DateTime date, CultureInfo culture)
        {
            if (date.Date == DateTime.Now.Date)
                return string.Empty;

            if (date.Date == DateTime.Now.Date.AddDays(1).Date)
                return "Tomorrow: ";

            return date.ToString(culture.DateTimeFormat.ShortDatePattern, culture) + ": ";
        }
    }
}
